/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MatrixCalculation;

import java.text.DecimalFormat;

/**
 *
 * @author Brahmarup
 */
public class SimilarityMatrix {


    private double mean[];
    private double scaledMatrix[][];
    private double similarityMatrix[][];
    private double alpha = 0.5;
    private double ratMean[][];
    
    public double[] getMean() {
        return mean;
    }

    public void setMean(double[] mean) {
        this.mean = mean;
    }
    
    public void prepareMean(RatingMatrix rm){
        //mean[] = new double[]
        this.mean = new double[rm.getNoOfUsers()];
        double sum = 0;
        
        for(int i = 0;i<rm.getNoOfUsers();i++){
            sum = 0;
            for(int j = 0;j<rm.getNoOfServices();j++){
                sum = sum + rm.getRatMatrix()[i][j];
            }
            mean[i]= sum/(double)rm.getNoOfServices();
            //System.out.println(mean[i] + ":mean["+i+"]");
        }
    }
    private void RatingMean(RatingMatrix rm){
        this.ratMean = new double[rm.getNoOfUsers()][rm.getNoOfServices()];
        for(int i = 0;i<rm.getNoOfUsers();i++){
            for(int j = 0;j<rm.getNoOfServices();j++){
                ratMean[i][j] = rm.getRatMatrix()[i][j] - this.getMean()[i];
            }
        }
    }

    public double[][] getRatMean() {
        return ratMean;
    }

    public void setRatMean(double[][] ratMean) {
        this.ratMean = ratMean;
    }
    public void calculateSim(){
        double numerator=0,denominator=0,sum1=0,sum2=0;
        //System.out.println(numerator);
        double sim[][]  = new double[rm.getNoOfUsers()][rm.getNoOfUsers()] ;
        double value;
        value = 0;
        for(int u=0;u<rm.getNoOfUsers();u++){
            for(int v=0;v<rm.getNoOfUsers();v++){
                numerator = 0;
                sum1 = 0;
                sum2 = 0;
                for(int i = 0; i<rm.getNoOfServices();i++)
                {
                    //System.out.println(u + " | " +v+ " | "+i);
                    numerator = numerator + ((rm.getRatMatrix()[u][i]-this.getMean()[u])* (rm.getRatMatrix()[v][i]-this.getMean()[v]));
                    //System.out.print((rm.getRatMatrix()[u][i]+ "-"+ this.getMean()[u]));
                    //System.out.print("*"+(rm.getRatMatrix()[v][i]+"-"+this.getMean()[v])+":");
                    sum1=sum1+(Math.pow((rm.getRatMatrix()[u][i]- this.getMean()[u]),2));
                    sum2=sum2+(Math.pow((rm.getRatMatrix()[v][i]- this.getMean()[v]),2));
                }
                //System.out.println(u+ " " +v+" " +numerator);
                denominator = Math.sqrt(sum1*sum2);
                //System.out.println(u + " " +v +" " + denominator);
                
                value=numerator/denominator;
                sim[u][v] = this.RoundTo2Decimals(value);
                //System.out.println("Sim["+u+"]["+v+"]: " + sim[u][v]);
                //System.out.println();
            }
            
        }
        this.setSimilarityMatrix(sim);
    }
    
    public void print(double[][] sim){
        for(int u =0;u<rm.getNoOfUsers();u++){
            for(int v = 0;v<rm.getNoOfUsers();v++) {
                System.out.print("\tsim["+u+"]["+v+"]"+ sim[u][v]);
            }
            System.out.println();
        }
    }
    
    public double[][] getSimilarityMatrix() {
        return similarityMatrix;
    }

    public void setSimilarityMatrix(double[][] similarityMatrix) {
        this.similarityMatrix = similarityMatrix;
    }

    public int[][] getSimMat() {
        return simMat;
    }

    public void setSimMat(int[][] simMat) {
        this.simMat = simMat;
    }

    public double[][] getScaledMatrix() {
        return scaledMatrix;
    }

    public void setScaledMatrix(double[][] scaledMatrix) {
        this.scaledMatrix = scaledMatrix;
    }
    
    public void scaledSimilarityMatrix(){
        this.scaledMatrix = new double[rm.getNoOfServices()][rm.getNoOfUsers()];
        for(int i = 0;i<rm.getNoOfServices();i++){
            for(int j = 0;j<rm.getNoOfUsers();j++){
                this.scaledMatrix[i][j] = this.RoundTo2Decimals(this.alpha*this.getSimilarityMatrix()[i][j]+this.alpha);
            }
        }
    }
    
    double RoundTo2Decimals(double val) {
            DecimalFormat df2 = new DecimalFormat("###.##");
        return Double.valueOf(df2.format(val));
    }

    public void calculteMean()
    {
        //System.out.print("Mean");
        for(i=0;i<10;i++)
        {
            sum=0;
            for(j=0;j<10;j++)
            {
               sum = sum + this.getRm().getRatMatrix()[i][j];
            }
            mean[j]=sum/10;
            //System.out.print(mean[j]+" ");
        }
        setMean(mean);
    }
    
    int sum,i,j;
    RatingMatrix rm;
    private int[][] simMat;

    public RatingMatrix getRm() {
        return rm;
    }

    public void setRm(RatingMatrix rm) {
        this.rm = rm;
    }
    public SimilarityMatrix(RatingMatrix rm) {
        this.setRm(rm);
        this.prepareMean(rm);
        this.calculateSim();
        this.scaledSimilarityMatrix();
        //this.print(this.getSimilarityMatrix());
        //this.calculteMean();       
    }

    
    public static void main(String args[])
    {
        RatingMatrix rm = new RatingMatrix();
        
        SimilarityMatrix sm = new SimilarityMatrix(rm);
        /*sm.setRm(rm);
        sm.prepareMean(rm);
        sm.calculateSim();
        sm.scaledSimilarityMatrix();
        //sm.print(sm.getScaledMatrix()); 
        //sm.NormalizedMatrix();
        //sm.print(sm.getSimilarityMatrix());
        */
    }
}